package com.hoapital.outpbillwork.billWorkHandler;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.hoapital.outpbillwork.module.controller.vo.ApplyInfo;
import com.hoapital.outpbillwork.module.controller.vo.ItemData;
import com.hoapital.outpbillwork.module.controller.vo.OrderInfo;
import com.hoapital.outpbillwork.module.entity.*;
import com.hoapital.outpbillwork.module.mapper.ExamAppointsMapper;
import com.hoapital.outpbillwork.module.mapper.ExamBillItemsMapper;
import com.hoapital.outpbillwork.module.mapper.ExamItemsMapper;
import com.hoapital.outpbillwork.module.mapper.OutpOrderDescTempMapper;
import com.hoapital.outpbillwork.module.service.OutpDoctorAssistantService;
import com.hospital.common.core.constants.AllFinalValueUtils;
import com.hospital.common.core.constants.OrderConstant;
import com.hospital.common.core.exception.ExceptionHelp;
import com.hospital.common.core.exception.ExceptionHelpEnum;
import com.hospital.common.core.hl7Model.hospitalWork.BATCH;
import com.hoapital.outpbillwork.function.setValue.SetFunctionHL7;

import com.hospital.common.core.module.controller.vo.CancelOrder;
import com.hospital.common.core.module.controller.vo.OrderContent;
import com.hospital.common.core.module.controller.vo.Receive;
import com.hoapital.outpbillwork.module.mapper.LabTestMasterMapper;
import com.hospital.common.core.result.SuccessTip;
import com.hospital.common.core.result.Tip;
import com.hospital.common.core.utils.DateUtil;
import com.hospital.common.core.utils.SpringContextHolder;
import com.hospital.common.core.utils.XMLUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lvyao
 * @description 门诊开单检查
 * @date 2022/2/25
 */

@Transactional(rollbackFor = Exception.class)
public class ExamOrderBusiness extends AbstractOrderWorkBusiness {


    private LabTestMasterMapper labTestMasterMapper = SpringContextHolder.getBean(LabTestMasterMapper.class);

    private ExamAppointsMapper examAppointsMapper = SpringContextHolder.getBean(ExamAppointsMapper.class);

    private ExamItemsMapper examItemsMapper = SpringContextHolder.getBean(ExamItemsMapper.class);

    private ExamBillItemsMapper examBillItemsMapper = SpringContextHolder.getBean(ExamBillItemsMapper.class);

    private OutpDoctorAssistantService outpDoctorAssistantService = SpringContextHolder.getBean(OutpDoctorAssistantService.class);

    private OutpOrderDescTempMapper outpOrderDescTempMapper = SpringContextHolder.getBean(OutpOrderDescTempMapper.class);

    @Override
    public ExceptionHelp checkOtherOrder(OrderInfo orderInfo) throws ExceptionHelp {
        return null;
    }

    @Override
    public ExceptionHelp checkOtherExpecOrder(ApplyInfo orderInfo) throws ExceptionHelp {
        return null;
    }

    @Override
    public String getOrderNotemp(OrderContent orderContent, Timestamp visitDate, int visitNo) {
        String orderNO = "";
//        if (orderContent.getOrderType().equals("C")||orderContent.getOrderType().equals("D")){
        String testNoDual = examAppointsMapper.getExamNoString();
        orderNO = orderContent.getOrderNo() == null || orderContent.getOrderNo().equals("") ?
                String.format("%04d", Integer.parseInt(testNoDual)) : orderContent.getOrderNo();
//        }
        return orderNO;
    }


    @Override
    protected ExamAppoints doOtherInfo(List<ItemData> itemDataList, String testNo, PatientInfo patientInfo,
                                       OrderContent order, int age, String testCause, String clininDiag, Timestamp visitDate,
                                       int visitNo, String subject, int outpId) {
        ExamAppoints examAppoints = new ExamAppoints();
        com.hoapital.outpbillwork.module.entity.ExamRptPattern examClass = examAppointsMapper.getExamClass(itemDataList.get(0).getItemCode());
        if (ObjectUtil.isNull(examClass)) {
            throw new ExceptionHelp(ExceptionHelpEnum.NULL_EXAMCLASS);
        }
        examAppoints.setExamNo(testNo);
        examAppoints.setPatientId(patientInfo.getPatientId());
        examAppoints.setVisitId(outpId);
        examAppoints.setName(patientInfo.getName());
        examAppoints.setNamePhonetic(patientInfo.getNamePhonetic());
        examAppoints.setChargeType(patientInfo.getChargeType());
        examAppoints.setSex(patientInfo.getSex());
        examAppoints.setDateOfBirth(patientInfo.getDateOfBirth());
        examAppoints.setBirthPlace(patientInfo.getBirthPlace());
        examAppoints.setIdentity(patientInfo.getIdentity());
        examAppoints.setMailingAddress(patientInfo.getMailingAddress());
        examAppoints.setZipCode(patientInfo.getZipCode());
        examAppoints.setPhoneNumber(patientInfo.getPhoneNumberHome());
        examAppoints.setExamClass(StringUtils.isBlank(order.getExamClass()) ? examClass.getExamClass() : order.getExamClass());
        examAppoints.setExamSubClass(StringUtils.isBlank(order.getExamSubClass()) ? examClass.getExamSubClass() : order.getExamSubClass());
        examAppoints.setClinDiag(order.getClinicDiag());
        examAppoints.setClinSymp("");
        examAppoints.setPhysSign("");
        examAppoints.setPatientSource(testCause.equals(AllFinalValueUtils.OUTP_CAUSE) ? AllFinalValueUtils.PAT_SOURCE_OUTP :
                testCause.equals(AllFinalValueUtils.INP_CAUSE) ? AllFinalValueUtils.PAT_SOURCE_INP : AllFinalValueUtils.PAT_SOURCE_OTHER);
        examAppoints.setTestCause(testCause);
        examAppoints.setReqDateTime(visitDate);
        examAppoints.setReqDept(order.getOrderedByDept());
        examAppoints.setReqPhysician(order.getOrderedByDoctor());
        examAppoints.setCharges(new BigDecimal(0));
        examAppoints.setCosts(new BigDecimal(0));
        examAppoints.setPerformedBy(order.getPerformedBy());
        return examAppoints;
    }

    @Override
    protected ExamItems doOtherInfoDeatil(String orderNo, int itemNo, String itemCode, String itemName, BigDecimal price, BigDecimal charges) {
        ExamItems examItems = new ExamItems();
        examItems.setExamNo(orderNo);
        examItems.setExamItemNo(itemNo);
        examItems.setExamItem(itemName);
        examItems.setExamItemCode(itemCode);
        examItems.setCosts(price);
        return examItems;
    }

    @Override
    protected BATCH packageMessage(OutpMedrec outpMedrec, List<OutpOrderDescTemp> outpOrderDescTempList,
                                   List<Object> objectMaster, List<Object> objectDetail, OrderInfo orderInfo,
                                   PatientInfo patientInfo, String orc1, String orc5) {
        Object object = objectMaster.get(0);
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(object));
        String examClass = jsonObject.getString("examClass");
        String examSubClass = jsonObject.getString("examSubClass");
        String examToApp = examAppointsMapper.getExamToApp(AllFinalValueUtils.EXAM, examClass, examSubClass);
        String toApp = StringUtils.isBlank(examToApp) ? AllFinalValueUtils.MESSAGE_FROM_EXAM : examToApp;
        if (StringUtils.isBlank(toApp)) {
            return null;
        }
        return SetFunctionHL7.packageOmallMessage(outpMedrec, outpOrderDescTempList, objectMaster,
                objectDetail, orderInfo.getHospitalCode(), orderInfo.getHospitalName(), orderInfo.getOutpOrInp(),
                patientInfo, orc1, orc5, labTestMasterMapper, AllFinalValueUtils.EXAM, toApp,
                AllFinalValueUtils.MESSAGE_EVENT_EXAM, AllFinalValueUtils.MESSAGE_EVENT_NAME_EXAM);
    }


    @Override
    public ExamBillItems doOtherBillDetail(String testNo, int outpId, Timestamp visitDate, int visitNo, int itemNo, ClinicItemBill clinicItemBill,
                                           ItemData itemData, OrderContent orderContent, String patientId) {
        ExamBillItems examBillItems = new ExamBillItems();
        examBillItems.setExamNo(testNo);
        examBillItems.setExamItemNo(itemNo);
        examBillItems.setPatientId(patientId);
        examBillItems.setChargeItemNo(clinicItemBill.getChargeItemNo());
        examBillItems.setVisitId(outpId);
        examBillItems.setItemClass(clinicItemBill.getItemClass());
        examBillItems.setItemName(clinicItemBill.getItemName());
        examBillItems.setItemCode(clinicItemBill.getItemCode());
        examBillItems.setItemSpec(clinicItemBill.getItemSpec());
        examBillItems.setAmount(clinicItemBill.getAmount().multiply(itemData.getAmount()));
        examBillItems.setUnits(clinicItemBill.getUnits());
        examBillItems.setOrderedBy(orderContent.getOrderedByDept());
        examBillItems.setPerformedBy(orderContent.getPerformedBy());
        examBillItems.setCosts(itemData.getCosts());
        examBillItems.setCharges(itemData.getCharges());
        examBillItems.setBillingDateTime(visitDate);
        examBillItems.setOperatorNo(AllFinalValueUtils.ALL_OPERATOR);
        examBillItems.setVerifiedIndicator(AllFinalValueUtils.EXAM_VERF_INDICATOR);
        return examBillItems;
    }

    @Override
    public Object doAfterData(String type, Object object, BigDecimal costs, BigDecimal charges) {
        Object objecdetail = null;
        switch (type) {
            case OrderConstant.ITEM:
                ItemData itemData = (ItemData) object;
                itemData.setCosts(costs);
                itemData.setCharges(charges);
                objecdetail = doOtherInfoDeatil(itemData.getOrderNo(), itemData.getItemNo(), itemData.getItemCode(), itemData.getItemName(), itemData.getCosts(), charges);
                return objecdetail;
            default:
                ExamAppoints examAppoints = (ExamAppoints) object;
                examAppoints.setCosts(costs);
                examAppoints.setCharges(charges);
                return examAppoints;
        }

    }

    @Override
    public String getReplaceString(BATCH getHl7LabMessage) {
        String utf8 = XMLUtil.convertToXml(getHl7LabMessage).replace(AllFinalValueUtils.MESSAGE_HL7_REPLACE_EXAM_BEF_TARGET_A,
                "").replace(AllFinalValueUtils.MESSAGE_HL7_REPLACE_EXAM_AFT_TARGET_B,
                "").replace(AllFinalValueUtils.UNICODE_DEFAULT_TARGET, AllFinalValueUtils.UNICODE_DEFAULT_REPLACEMENT)
                .replace("<type>D</type>", "");
        return utf8;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateOtherTable(ClinicMaster clinicMaster, OutpMedrec outpMedrec, List<OutpOrderDescTemp> outpOrderDescTempList, List<OutpBillItemsTemp> outpBillItemsTempList,
                                    List<OutpDoctorAssistant> outpDoctorAssistantList,
                                    List<Object> objectMasterList, List<Object> objectItemsList, List<Object> objectBillitemsList,
                                    OutpPrepayRcptTemp outpPrepayRcptTemp, List<OrderVsBillno> orderVsBillnoList) throws ExceptionHelp {


        return outpDoctorAssistantService.updateAllTab(AllFinalValueUtils.EXAM, clinicMaster, outpMedrec, outpOrderDescTempList, outpBillItemsTempList, outpDoctorAssistantList, objectMasterList, objectItemsList, objectBillitemsList, outpPrepayRcptTemp, orderVsBillnoList);
    }


    @Override
    public Tip billWork(Receive receive, HttpServletRequest request) throws ExceptionHelp {
        return null;
    }

    @Override
    public Tip orderCancel(CancelOrder CancelOrder, HttpServletRequest request) throws ExceptionHelp {
        return null;
    }

    @Override
    public Tip sendApplyHl7File(OrderInfo orderInfo, String oneKey, String msgType) throws ExceptionHelp {
        Map<String, Object> hl7ApplyBaseData = getHl7ApplyBaseData(oneKey, orderInfo.getPatInfo().getPatientId(), orderInfo.getVisitId());
        List<Object> objectMasterList = new ArrayList<>();
        List<Object> objectDetailList = new ArrayList<>();
        List<OutpOrderDescTemp> outpOrderDescTempList = new ArrayList<>();
        for (ApplyInfo applyInfo : orderInfo.getApplyInfo()) {
            objectMasterList.add(examAppointsMapper.selectById(applyInfo.getOrder().getOrderNo()));
            Map<String, Object> map = new HashMap<>();
            map.put(AllFinalValueUtils.EXAM_NO, applyInfo.getOrder().getOrderNo());
            objectDetailList.addAll(examItemsMapper.selectByMap(map));

            Map<String, Object> mapOrder = new HashMap<>();
            mapOrder.put(AllFinalValueUtils.OUTP_VISIT_NO, String.valueOf(applyInfo.getOrder().getOrderNoumber()));
            mapOrder.put(AllFinalValueUtils.VISIT_DATE, DateUtil.parseTime(applyInfo.getOrder().getOrderDate()));
            outpOrderDescTempList.addAll(outpOrderDescTempMapper.selectByMap(mapOrder));

            BATCH hl7message = packageMessage((OutpMedrec) hl7ApplyBaseData.get("outpMedrec"), outpOrderDescTempList,
                    objectMasterList, objectDetailList,
                    orderInfo, (PatientInfo) hl7ApplyBaseData.get("patientInfo"), "NW", "SC");
            //xml申请文件保存并推送
            oneKey = DateUtil.formatDate(DateUtil.parseTime(applyInfo.getOrder().getOrderDate()), "yyyyMMddHHmmss") + applyInfo.getOrder().getOrderNoumber();
            boolean push = saveApplyHl7message(orderInfo.getHospitalCode(), orderInfo.getHospitalName(), oneKey, hl7message, msgType);
            if (!push) {
                throw new ExceptionHelp(ExceptionHelpEnum.SEND_APPLY_MSG_FILAD);
            }
            objectMasterList = null;
            objectDetailList = null;
        }
        return new SuccessTip();
    }


}
